package com.lmabbe.gateway.filter;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.lmabbe.common.global.constant.GlobalConstant;
import com.lmabbe.common.global.enums.ClientTypeEnum;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 请求头参数判断
 *
 * @author lmabbe
 */
@Component
public class HeaderCheckFilter implements GlobalFilter, Ordered {

    /**
     * 返回response
     *
     * @param exchange
     * @param message  异常信息
     * @return
     */
    public static Mono<Void> errorInfo(ServerWebExchange exchange, String message) {
        // 自定义返回格式
        Map<String, Object> resultMap = new HashMap<>(8);
        resultMap.put("code", 405);
        resultMap.put("message", message);
        resultMap.put("timestamp", System.currentTimeMillis());
        return Mono.defer(() -> {
            byte[] bytes = JSONObject.toJSONString(resultMap).getBytes();
            ServerHttpResponse response = exchange.getResponse();
            response.getHeaders().add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
            DataBuffer buffer = response.bufferFactory().wrap(bytes);
            return response.writeWith(Flux.just(buffer));
        });
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        if (request.getURI().getPath().contains("oauth/check_token")
                || request.getURI().getPath().contains("system/version")
                || request.getURI().getPath().contains("system/config")
                || request.getURI().getPath().contains("v3/api-docs")) {
            return chain.filter(exchange);
        }
        List<String> tenantId = request.getHeaders().get(GlobalConstant.SYSTEM.TENANT_ID);
        if (null == tenantId || tenantId.size() != 1) {
            return errorInfo(exchange, "租户信息错误");
        }
        if (StrUtil.isEmpty(tenantId.get(0))) {
            return errorInfo(exchange, "租户信息错误");
        }

        List<String> fromClient = request.getHeaders().get(GlobalConstant.SYSTEM.FROM_CLIENT);
        if (null == fromClient || fromClient.size() != 1) {
            return errorInfo(exchange, "客户端信息错误");
        }
        ClientTypeEnum clientTypeByCode = ClientTypeEnum.getClientTypeByCode(fromClient.get(0));
        if (clientTypeByCode == ClientTypeEnum.UNKNOWN) {
            return errorInfo(exchange, "客户端信息错误");
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }
}
